package com.region.loadbalancer;

import com.region.loadbalancer.listener.ConnectionListener;
import com.region.loadbalancer.monitor.stat.DetectionConnection;
import com.region.loadbalancer.monitor.stat.SocketDetectionConnection;
import com.region.loadbalancer.policy.BalancerPolicy;
import com.region.loadbalancer.policy.RoundRobinPolicy;

import java.util.Collections;
import java.util.List;
import java.util.concurrent.TimeUnit;

/**
 * Load Balancing Config
 *
 * @author liujieyu
 * @date 2023/5/25 23:52
 * @desciption
 */
public class LoadBalancerConfig {

    /**
     * Number of monitoring cores
     */
    private int monitorCore;

    /**
     * Duration of the detection
     */
    private int detectionDuration;

    /**
     * The type of detection
     */
    private TimeUnit detectionType;

    /**
     * Default config of Balancer Policy, The globally configured policy is used to copy a new object by calling the deepClone method
     * @see BalancerPolicy#deepClone()
     */
    private BalancerPolicy policy;

    /**
     * Default Listening the status of server
     */
    private List<ConnectionListener> listeners;

    /**
     * Default Detection Connection Status
     */
    private DetectionConnection detectionConnection;

    /**
     * Whether to open the automated scanning service status
     */
    private boolean autoDetect;

    /**
     * Checking the availability of a service before selecting it
     */
    private boolean detectOnBorrow;

    public LoadBalancerConfig() {
        this(Runtime.getRuntime().availableProcessors(), 10, TimeUnit.SECONDS);
    }

    public LoadBalancerConfig(int monitorCore, int detectionDuration, TimeUnit detectionType) {
        this(monitorCore, detectionDuration, detectionType, false, false);
    }

    public LoadBalancerConfig(int monitorCore, int detectionDuration, TimeUnit detectionType, boolean autoDetect, boolean detectOnBorrow) {
        this(monitorCore, detectionDuration, detectionType, new RoundRobinPolicy(),
                Collections.EMPTY_LIST, new SocketDetectionConnection(), autoDetect, detectOnBorrow);
    }

    public LoadBalancerConfig(int monitorCore, int detectionDuration, TimeUnit detectionType, BalancerPolicy policy,
                              List<ConnectionListener> listeners, DetectionConnection detectionConnection, boolean autoDetect, boolean detectOnBorrow) {
        this.monitorCore = monitorCore;
        this.detectionDuration = detectionDuration;
        this.detectionType = detectionType;
        this.policy = policy;
        this.listeners = listeners;
        this.detectionConnection = detectionConnection;
        this.autoDetect = autoDetect;
        this.detectOnBorrow = detectOnBorrow;
    }

    public int getMonitorCore() {
        return monitorCore;
    }

    public void setMonitorCore(int monitorCore) {
        this.monitorCore = monitorCore;
    }

    public int getDetectionDuration() {
        return detectionDuration;
    }

    public void setDetectionDuration(int detectionDuration) {
        this.detectionDuration = detectionDuration;
    }

    public TimeUnit getDetectionType() {
        return detectionType;
    }

    public void setDetectionType(TimeUnit detectionType) {
        this.detectionType = detectionType;
    }

    public BalancerPolicy getPolicy() {
        return policy;
    }

    public void setPolicy(BalancerPolicy policy) {
        this.policy = policy;
    }

    public List<ConnectionListener> getListeners() {
        return listeners;
    }

    public void setListeners(List<ConnectionListener> listeners) {
        this.listeners = listeners;
    }

    public DetectionConnection getDetectionConnection() {
        return detectionConnection;
    }

    public void setDetectionConnection(DetectionConnection detectionConnection) {
        this.detectionConnection = detectionConnection;
    }

    public boolean isAutoDetect() {
        return autoDetect;
    }

    public void setAutoDetect(boolean autoDetect) {
        this.autoDetect = autoDetect;
    }

    public boolean isDetectOnBorrow() {
        return detectOnBorrow;
    }

    public void setDetectOnBorrow(boolean detectOnBorrow) {
        this.detectOnBorrow = detectOnBorrow;
    }
}
